package com.lvmama.rhino.web;

import com.github.pagehelper.PageInfo;
import com.lvmama.entity.system.Menu;
import com.lvmama.entity.system.SysUser;
import com.lvmama.rhino.base.BaseControllerSupport;
import com.lvmama.rhino.enums.CommonParentType;
import com.lvmama.rhino.pojo.*;
import com.lvmama.rhino.pojo.funnel.FlowFunnelData;
import com.lvmama.rhino.pojo.funnel.FlowStatisticsFunnel;
import com.lvmama.rhino.service.FlowStatisticsService;
import com.lvmama.rhino.service.FunnelService;
import com.lvmama.rhino.service.MenuService;
import com.lvmama.rhino.service.StatisticCodeService;
import com.lvmama.rhino.web.sso.SystemSession;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

/**
 * @author yuanchi
 * @ClassName: TrafficController
 * @Description: TODO 流量统计
 * @date 2016年10月24日 下午1:51:00
 */
@Controller
@RequestMapping("traffic")
public class TrafficController extends BaseControllerSupport {

    private static Map<String, ContinuityCode> ccMap = new HashMap<String, ContinuityCode>();
    @Autowired
    FlowStatisticsService flowStatisticsService;
    @Autowired
    private StatisticCodeService statisticCodeService;
    @Autowired
    private FunnelService funnelService;
    @Autowired
    private ElasticsearchTemplate template;
    @Autowired
    private MenuService menuService;

    /**
     * @param @param  map
     * @param @return 设定文件
     * @return Map<K,V> 返回类型
     * @throws
     * @Title: sortByValueDesc
     * @Description: map降序排序
     */
    private static <K, V extends Comparable<? super V>> Map<K, V> sortByValueDesc(
            Map<K, V> map) {
        List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(
                map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return (o2.getValue()).compareTo(o1.getValue());
            }
        });
        Map<K, V> result = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

    /**
     * @param @param  map
     * @param @return 设定文件
     * @return Map<K,V> 返回类型
     * @throws
     * @Title: sortByValueAsc
     * @Description: map升序排序
     */
    private static <K, V extends Comparable<? super V>> Map<K, V> sortByValueAsc(
            Map<K, V> map) {
        List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(
                map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return (o1.getValue()).compareTo(o2.getValue());
            }
        });

        Map<K, V> result = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

    @RequestMapping("landPageFlow")
    public String landPageFlow(ModelMap model) {
        return "application/landPageFlowList";
    }

    /**
     * @Title: getChildCodeList
     * @Description: 获取子集code信息
     */
    @RequestMapping("getChildCodeList")
    @ResponseBody
    public Map<String, Object> getChildCodeList(int parent_id) {
        List<StatisticCode> codeList = statisticCodeService
                .queryChildCodeListByParentId(parent_id);
        Map<String, Object> resultMap = new java.util.HashMap<String, Object>();
        resultMap.put("codeList", codeList);
        return resultMap;
    }

    @RequestMapping("transform")
    public String transform(ModelMap model) {
        // 通过枚举获得品类的信息
        CommonParentType[] getVSTProduct = CommonParentType.geAllCategory();
        List<CommonParentType> vSTProductlist = Arrays.asList(getVSTProduct);
        model.addAttribute("vSTProductlist", vSTProductlist);
        // 从数据库查询SEM着陆页或SEO着陆页名称
        List<StatisticCode> semSeoCodeList = statisticCodeService
                .getLikeCodeObj("3");
        for (int i = 0; i < semSeoCodeList.size(); i++) {
            String code = semSeoCodeList.get(i).getCode();
            if (code.equals("3")) {
                semSeoCodeList.get(i).setName("全部");
                semSeoCodeList.get(i).setCode("");
            } else if (code.equals("3zhTi") || code.equals("3PinD")) {
                semSeoCodeList.remove(i);
            }
        }
        model.addAttribute("semSeoCodeList", semSeoCodeList);
        // 从数据库查询SEO流量来源
        List<StatisticCode> seoCodeList = statisticCodeService
                .getLikeCodeObj("123");
        for (StatisticCode statisticCode : seoCodeList) {
            if (statisticCode.getCode().equals("123")) {
                statisticCode.setName("全部");
                statisticCode.setCode("");
            }
        }
        model.addAttribute("seoCodeList", seoCodeList);
        // 从数据库查询社交分享
        List<StatisticCode> socialCodeList = statisticCodeService
                .getLikeCodeObj("121");
        for (StatisticCode statisticCode : socialCodeList) {
            if (statisticCode.getCode().equals("121")) {
                statisticCode.setName("全部");
                statisticCode.setCode("");
            }
        }
        model.addAttribute("socialCodeList", socialCodeList);
        // 从数据库查询专题页
        /*
         * List<StatisticCode> topicList =
		 * statisticCodeService.getLikeCodeObj("3zhTi"); for(StatisticCode
		 * statisticCode : topicList){
		 * if(statisticCode.getCode().equals("3zhTi")){
		 * statisticCode.setName("全部"); statisticCode.setCode(""); } }
		 * model.addAttribute("topicList", topicList);
		 */
        return "application/transformList";
    }

    @RequestMapping("upDownstream")
    public String upDownstream(ModelMap model) {
        return "application/upDownstreamList";
    }

    /**
     * 根据平台获得版本类型
     *
     * @param platForm
     * @return
     */
    @RequestMapping("appVersion")
    @ResponseBody
    public Map<String, Object> queryAppVersion(String platForm) {
        Map<String, Object> result = getResult();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        // 根据code码获得其子级的code码信息
        List<StatisticCode> codeList = statisticCodeService.getLikeCodeObj("2");
        if (platForm != "") {
            for (StatisticCode statisticCode : codeList) {
                if (statisticCode.getName().startsWith(platForm)) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    String appVersionName = statisticCode.getName().replace(
                            platForm, "");
                    map.put("name", appVersionName);
                    map.put("value", statisticCode.getCode());
                    list.add(map);
                }
            }
        }
        result.put("code", "1");
        result.put("msg", list);
        return result;
    }

    /**
     * 根据业务类型获得页面名称
     *
     * @param categoryId
     * @return
     */
    @RequestMapping("queryPageCode")
    @ResponseBody
    public Map<String, Object> queryPageCode(String categoryId) {
        Map<String, Object> result = getResult();
        // 当业务类型为"频道""专题"时
        if (categoryId.equals("3PinD") || categoryId.equals("3zhTi")) {
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            // 根据code码获得其子级的code码信息
            List<StatisticCode> codeList = statisticCodeService
                    .getParentAndChildrenLikeCodeObj(categoryId);
            for (StatisticCode statisticCode : codeList) {
                if (statisticCode.getCode().equals("3PinD")
                        || statisticCode.getCode().equals("3zhTi")) {
                    statisticCode.setName("全部");
                }
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("name", statisticCode.getName());
                map.put("value", statisticCode.getCode());
                list.add(map);
            }
            result.put("code", "1");
            result.put("msg", list);
        } else if (categoryId.equals("3XagQ") || categoryId.equals("3TXDD")
                || categoryId.equals("3DaiZ") || categoryId.equals("3ZhiW")) {
            // 通过枚举获得品类的信息
            CommonParentType[] getVSTProduct = CommonParentType.geAllCategory();
            List<CommonParentType> vSTProductlist = Arrays
                    .asList(getVSTProduct);
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            for (CommonParentType CommonParentType : vSTProductlist) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("name", CommonParentType.getShowName());
                map.put("value", CommonParentType.getValue());
                list.add(map);
            }
            result.put("code", "1");
            result.put("msg", list);
        } else {
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            Map<String, Object> map = new HashMap<>();
            map.put("name", "全部");
            map.put("value", "");
            list.add(map);
            result.put("code", "1");
            result.put("msg", list);
        }
        return result;
    }

    /**
     * 着陆页流量-着陆页详情
     *
     * @param flow_type
     * @param plat_form
     * @param channel1
     * @param channel2
     * @param chooseTime
     * @return
     * @throws Exception
     */
    @RequestMapping("landingPage")
    @ResponseBody
    public Map<String, Object> landingPageData(
            @RequestParam("flow_type") String flow_type,
            @RequestParam("plat_form") String plat_form,
            @RequestParam("channel1") String channel1,
            @RequestParam("channel2") String channel2,
            @RequestParam("chooseTime") String chooseTime) throws Exception {
        int defaultLength = 10;
        // 处理起始日期
        DateTimeFormatter formater = DateTimeFormat
                .forPattern("MM/dd/yyyy HH:mm:ss");
        Date start_date = DateTime.parse(
                chooseTime.split("-")[0].trim() + " 00:00:00", formater)
                .toDate();
        Date end_date = DateTime.parse(
                chooseTime.split("-")[1].trim() + " 23:59:59", formater)
                .toDate();

        Map<String, Object> retMap = new HashMap<String, Object>();
        String[] depthxAxis = new String[defaultLength];
        Long[] depthseries = new Long[defaultLength];
        String[] timexAxis = new String[defaultLength];
        Long[] timeseries = new Long[defaultLength];

        // 获取平台相关code
        List<String> statisticCodeList = new ArrayList<String>();
        if (plat_form.equals("app")) {
            statisticCodeList = statisticCodeService.getDeviceCodeApp();
        } else if (plat_form.equals("ios")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("ios");
        } else if (plat_form.equals("android")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("android");
        } else if (plat_form.equals("wap")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("wap");
        } else if (plat_form.equals("PC")) {//增加pc渠道，shibing 20170823
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("PC");
        }
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("start_date", start_date);
        param.put("end_date", end_date);
        String code = "";
        if ("internalFlow".equals(flow_type)) {
            param.put("plat_form", plat_form);
            code = "11";
        } else if ("outFlow".equals(flow_type)) {
            // 如果渠道1不选择 筛选全部外部渠道code
            if (StringUtils.isEmpty(channel1)) {
                code = "12";
            } else {
                // 如果渠道2不选 删选渠道1所有子集code
                if (StringUtils.isEmpty(channel2)) {
                    code = channel1.split("_")[1];
                } else {
                    code = channel2.split("_")[1];
                }
            }
        }
        List<String> channelCodeList = statisticCodeService
                .getChannelCode(code);
        param.put("statisticCodeList", statisticCodeList.size() == 0 ? null
                : statisticCodeList);// 平台code
        param.put("channelCodeList", channelCodeList);// 渠道code

        Map<String, List<FlowStatisticsVo>> resultMap = flowStatisticsService
                .landingPageDepthTime(param);
        List<FlowStatisticsVo> accessTimeMap = resultMap.get("AccessTime");
        List<FlowStatisticsVo> depthMap = resultMap.get("Depth");
        List<FlowStatisticsVo> landingPageMap = resultMap.get("LandingPage");

        long accessAmount = 0l;
        long timeAmount = 0l;
        for (FlowStatisticsVo flowStatisticsVo : accessTimeMap) {
            if (flowStatisticsVo != null && flowStatisticsVo.getDuration() < 0) {
                flowStatisticsVo.setDuration(Math.abs(flowStatisticsVo
                        .getDuration()));
            }
            accessAmount += flowStatisticsVo.getAmount();
            timeAmount += flowStatisticsVo.getDuration()
                    * flowStatisticsVo.getAmount();
        }
        Collections.sort(accessTimeMap, new Comparator<FlowStatisticsVo>() {
            @Override
            public int compare(FlowStatisticsVo o1, FlowStatisticsVo o2) {
                return o1.getDuration() >= o2.getDuration() ? 1 : -1;
            }
        });

        if (accessTimeMap != null && !accessTimeMap.isEmpty()) {
            Long sum = 0l;
            for (int i = 0; i < accessTimeMap.size(); i++) {
                if (i < defaultLength - 1) {
                    timexAxis[i] = accessTimeMap.get(i).getDuration() * 30 + "";
                    timeseries[i] = accessTimeMap.get(i).getAmount();
                } else if (i == accessTimeMap.size() - 1) {
                    timexAxis[defaultLength - 1] = accessTimeMap.get(
                            defaultLength - 1).getDuration()
                            * 30 + "+";
                    timeseries[defaultLength - 1] = sum
                            + accessTimeMap.get(i).getAmount();
                } else {
                    sum += accessTimeMap.get(i).getAmount();
                }
            }
        }
        long depthAmount = 0l;
        long sessionAmount = 0l;
        if (depthMap != null && !depthMap.isEmpty()) {
            Long sum = 0l;
            for (int i = 0; i < depthMap.size(); i++) {
                depthAmount += depthMap.get(i).getDepth()
                        * depthMap.get(i).getAmount();
                sessionAmount += depthMap.get(i).getAmount();
                if (i < defaultLength - 1) {
                    depthxAxis[i] = depthMap.get(i).getDepth() + "";
                    depthseries[i] = depthMap.get(i).getAmount();
                } else if (i == depthMap.size() - 1) {
                    depthxAxis[defaultLength - 1] = depthMap.get(
                            defaultLength - 1).getDepth()
                            + "+";
                    depthseries[defaultLength - 1] = sum
                            + depthMap.get(i).getAmount();
                } else {
                    sum += depthMap.get(i).getAmount();
                }
            }
        }
        Long amount = 0l;
        Long bounce_amount = 0l;
        if (landingPageMap != null && !landingPageMap.isEmpty()) {
            FlowStatisticsVo flowStatistics = landingPageMap.get(0);
            if (flowStatistics != null) {
                amount = flowStatistics.getAmount();
                bounce_amount = flowStatistics.getBounce_amount();
            }
        }

        DecimalFormat df = new DecimalFormat("#0.00");
        String avg_access_time = "0";
        String avg_access_depth = "0";
        if (accessAmount != 0) {
            avg_access_time = new DecimalFormat("#0").format((timeAmount
                    / accessAmount) / 1000);
        }
        if (sessionAmount != 0) {
            avg_access_depth = new DecimalFormat("#0").format(depthAmount
                    / sessionAmount);
        }
        retMap.put("avg_access_time", avg_access_time);
        retMap.put("avg_access_depth", avg_access_depth);

        retMap.put("depthxAxis", depthxAxis);
        retMap.put("depthseries", depthseries);
        retMap.put("timexAxis", timexAxis);
        retMap.put("timeseries", timeseries);
        retMap.put("amount", amount);
        if (amount != 0) {
            retMap.put("bounce_rate",
                    df.format(((double) bounce_amount) / amount * 100));
        } else {
            retMap.put("bounce_rate", "0.00");
        }
        retMap.put("bounce_amount", bounce_amount);
        return retMap;
    }

    @RequestMapping("regionData")
    @ResponseBody
    public Map<String, Object> regionData(
            @RequestParam("flow_type") String flow_type,
            @RequestParam("plat_form") String plat_form,
            @RequestParam("channel1") String channel1,
            @RequestParam("channel2") String channel2,
            @RequestParam("chooseTime") String chooseTime) throws Exception {
        // 处理起始日期
        DateTimeFormatter formater = DateTimeFormat
                .forPattern("MM/dd/yyyy HH:mm:ss");
        Date start_date = DateTime.parse(
                chooseTime.split("-")[0].trim() + " 00:00:00", formater)
                .toDate();
        Date end_date = DateTime.parse(
                chooseTime.split("-")[1].trim() + " 23:59:59", formater)
                .toDate();

        Map<String, Object> retMap = new HashMap<String, Object>();

        // 获取平台相关code
        List<String> statisticCodeList = new ArrayList<String>();
        if (plat_form.equals("app")) {
            statisticCodeList = statisticCodeService.getDeviceCodeApp();
        } else if (plat_form.equals("ios")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("ios");
        } else if (plat_form.equals("android")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("android");
        } else if (plat_form.equals("wap")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("wap");
        } else if (plat_form.equals("PC")) {//增加pc渠道，shibing 20170823
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("PC");
        }
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("start_date", start_date);
        param.put("end_date", end_date);
        String code = "";
        if ("internalFlow".equals(flow_type)) {
            param.put("plat_form", plat_form);
            code = "11";
        } else if ("outFlow".equals(flow_type)) {
            // 如果渠道1不选择 筛选全部外部渠道code
            if (channel1 == "") {
                code = "12";
            } else {
                // 如果渠道2不选 删选渠道1所有子集code
                if (channel2 == "") {
                    code = channel1.split("_")[1];
                } else {
                    code = channel2.split("_")[1];
                }
            }
        }
        List<String> channelCodeList = statisticCodeService
                .getChannelCode(code);
        param.put("statisticCodeList", statisticCodeList.size() == 0 ? null
                : statisticCodeList);// 平台code
        param.put("channelCodeList", channelCodeList);// 渠道code

        // //////////////////////地区分布图数据处理开始////////////////
        List<FlowStatisticsVo> landingRegionList = flowStatisticsService
                .landingRegionData(param);
        Map<String, Long> regionPreMap = new HashMap<>();
        List<String> regionList = new ArrayList<>();
        for (FlowStatisticsVo landingRegion : landingRegionList) {
            regionPreMap.put(landingRegion.getRegionCode(),
                    landingRegion.getAmount());
        }
        // 获取前十条数据
        regionPreMap = sortByValueDesc(regionPreMap);
        Map<String, Long> regionMap = new HashMap<>();
        int index = 0;
        long otherAmount = 0;
        for (Map.Entry<String, Long> entry : regionPreMap.entrySet()) {
            if (index < 10) {
                regionList.add(entry.getKey());
                regionMap.put(entry.getKey(), entry.getValue());
            } else {
                otherAmount += entry.getValue();
            }
            index++;
        }
        if (regionPreMap.size() > 10) {
            regionList.add("其他");
            regionMap.put("其他", otherAmount);
        }
        retMap.put("regionMap", regionMap);
        retMap.put("regionList", regionList);

        // //////////////////////地区分布图数据处理结束////////////////
        return retMap;
    }

    /**
     * 着陆页流量-着陆页详情tab分页
     *
     * @param flow_type
     * @param plat_form
     * @param channel1
     * @param channel2
     * @param chooseTime
     * @param start_num
     * @param page_size
     * @return
     * @throws Exception
     */
    @RequestMapping("landingPageByNum")
    @ResponseBody
    public Map<String, Object> landingPageByNum(String flow_type,
                                                String plat_form, String channel1, String channel2,
                                                String chooseTime, int sort, int start_num, int page_size) throws Exception {
        // 处理起始日期
        DateTimeFormatter formater = DateTimeFormat
                .forPattern("MM/dd/yyyy HH:mm:ss");
        Date start_date = DateTime.parse(
                chooseTime.split("-")[0].trim() + " 00:00:00", formater)
                .toDate();
        Date end_date = DateTime.parse(
                chooseTime.split("-")[1].trim() + " 23:59:59", formater)
                .toDate();
        // 获取平台相关code
        List<String> statisticCodeList = new ArrayList<String>();
        if (plat_form.equals("app")) {
            statisticCodeList = statisticCodeService.getDeviceCodeApp();
        } else if (plat_form.equals("ios")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("ios");
        } else if (plat_form.equals("android")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("android");
        } else if (plat_form.equals("wap")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("wap");
        } else if (plat_form.equals("PC")) {//增加pc流量统计，shibing 20170823
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("PC");
            //logger.info("---------------"+statisticCodeList);
        }
        //logger.info("---------------");
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("sort", sort);
        param.put("start_date", start_date);
        param.put("end_date", end_date);
        param.put("start_num", start_num);
        param.put("page_size", page_size);
        String code = "";
        if ("internalFlow".equals(flow_type)) {
            param.put("plat_form", plat_form);
            if (StringUtils.isNotEmpty(plat_form)) {
                param.put("groupSql", " group by page_code,platform_code_total,category_id ");
            } else {
                param.put("groupSql", " group by page_code,category_id ");
            }
            code = "11";
        } else if ("outFlow".equals(flow_type)) {
            // 如果渠道1不选择 筛选全部外部渠道code
            if (StringUtils.isEmpty(channel1)) {
                code = "12";
                param.put("groupSql", " group by channel_code ");
            } else {
                // 如果渠道2不选 删选渠道1所有子集code
                if (StringUtils.isEmpty(channel2)) {
                    code = channel1.split("_")[1];
                } else {
                    code = channel2.split("_")[1];
                }
                if ("12h".equals(channel1.split("_")[1])) {//sem
                    param.put("groupSql", " group by channel_code,page_code ");
                } else {
                    param.put("groupSql", " group by channel_code");
                }
            }
        }
        List<String> channelCodeList = statisticCodeService
                .getChannelCode(code);
        param.put("statisticCodeList", statisticCodeList.size() == 0 ? null
                : statisticCodeList);// 平台code
        param.put("channelCodeList", channelCodeList);// 渠道code

        PageInfo<FlowStatisticsVo> tabPageList = flowStatisticsService
                .landingPageTab(param);
        for (FlowStatisticsVo vo : tabPageList.getList()) {
            StatisticCode statisticParentCode = new StatisticCode();
            statisticParentCode.setCode(vo.getPage_code());
            // 根据条件查询code对象
            statisticParentCode = statisticCodeService
                    .selectStatisticCode(statisticParentCode);
            if (statisticParentCode != null) {
                // 无子集的页面名称取品类名称+页面名称
                if (vo.getPage_code().equals("3XagQ")
                        || vo.getPage_code().equals("3TXDD")
                        || vo.getPage_code().equals("3DaiZ")
                        || vo.getPage_code().equals("3ZhiW")) {
                    String categoryName = CommonParentType
                            .getCategoryShowName(vo.getCategory_id());
                    if (StringUtils.isNotEmpty(categoryName)) {
                        vo.setPage_name(categoryName + "-"
                                + statisticParentCode.getName());// 页面名称
                    } else {
                        vo.setPage_name("其它品类" + vo.getCategory_id() + "-" + statisticParentCode.getName());// 页面名称
                    }
                } else if (vo.getPage_code().startsWith("3PinD")) {
                    vo.setPage_name(statisticParentCode.getName()
                            + statisticParentCode.getParent().getName());// 页面名称
                } else {
                    vo.setPage_name(statisticParentCode.getName());// 页面名称
                }
            }
        }
        Map<String, Object> retMap = new HashMap<String, Object>();
        retMap.put("page", tabPageList);
        return retMap;
    }

    /**
     * 着陆页流量-着陆页排名
     *
     * @param ismatch
     * @param flow_type
     * @param plat_form
     * @param channel1
     * @param channel2
     * @param chooseTime
     * @param currentPage
     * @param page_size
     * @return
     * @throws ParseException
     */
    @RequestMapping("querylist")
    @ResponseBody
    public Map<String, Object> querylist(
            @RequestParam("ismatch") String ismatch,
            @RequestParam("flow_type") String flow_type,
            @RequestParam("plat_form") String plat_form,
            @RequestParam("channel1") String channel1,
            @RequestParam("channel2") String channel2,
            @RequestParam("chooseTime") String chooseTime,
            @RequestParam("currentPage") String currentPage,
            @RequestParam("page_size") String page_size) throws ParseException {
        // 获取平台相关code
        List<String> StatisticCodeList = new ArrayList<String>();
        if (plat_form.equals("app")) {
            StatisticCodeList = statisticCodeService.getDeviceCodeApp();
        } else if (plat_form.equals("ios")) {
            StatisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("ios");
        } else if (plat_form.equals("android")) {
            StatisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("android");
        } else if (plat_form.equals("wap")) {
            StatisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("wap");
        } else if (plat_form.equals("PC")) {
            StatisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("PC");
        } else {
            StatisticCodeList = null;
        }
        // 处理起始日期
        DateTimeFormatter formater = DateTimeFormat
                .forPattern("MM/dd/yyyy HH:mm:ss");
        Date start_date = DateTime.parse(
                chooseTime.split("-")[0].trim() + " 00:00:00", formater)
                .toDate();
        Date end_date = DateTime.parse(
                chooseTime.split("-")[1].trim() + " 23:59:59", formater)
                .toDate();
        // 组装查询条件
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("start_date", start_date);
        param.put("end_date", end_date);
        param.put("start_num", currentPage);
        param.put("page_size", page_size);
        String code = "";
        if ("internalFlow".equals(flow_type)) {
            code = "11";
        } else if ("outFlow".equals(flow_type)) {
            // 如果渠道1不选择 筛选全部外部渠道code
            if (StringUtils.isEmpty(channel1)) {
                code = "12";
            } else {
                // 如果渠道2不选 删选渠道1所有子集code
                if (StringUtils.isEmpty(channel2)) {
                    code = channel1.split("_")[1];
                } else {
                    code = channel2.split("_")[1];
                }
            }
        }
        List<String> channelCodeList = statisticCodeService
                .getChannelCode(code);
        param.put("statisticCodeList", StatisticCodeList);// 平台code
        param.put("channelCodeList", channelCodeList);// 渠道code
        PageInfo<FlowStatisticsVo> page = null;
        //查询
        if ("UV".equals(ismatch)) {
            //	logger.info("----------------sql----start-----------------------");
            page = flowStatisticsService.queryLandingPageList(param);
            //	logger.info("----------------sql----end-----------------------");
        } else {
            page = flowStatisticsService.queryAccessPageList(param);
        }
        List<FlowStatisticsVo> list = page.getList();

        for (FlowStatisticsVo vo : list) {
            StatisticCode statisticParentCode = new StatisticCode();
            statisticParentCode.setCode(vo.getPage_code());
            // 根据条件查询code对象
            statisticParentCode = statisticCodeService
                    .selectStatisticCode(statisticParentCode);
            if (statisticParentCode != null) {
                // 无子集的页面名称取品类名称+页面名称
                if (vo.getPage_code().equals("3XagQ")
                        || vo.getPage_code().equals("3TXDD")
                        || vo.getPage_code().equals("3DaiZ")
                        || vo.getPage_code().equals("3ZhiW")) {
                    String categoryName = CommonParentType
                            .getCategoryShowName(vo.getCategory_id());
                    if (StringUtils.isNotEmpty(categoryName)) {
                        vo.setPage_code(categoryName + "-"
                                + statisticParentCode.getName());// 页面名称
                    } else {
                        vo.setPage_code("其它品类-" + statisticParentCode.getName());// 页面名称
                    }
                } else if (vo.getPage_code().startsWith("3PinD")) {
                    vo.setPage_code(statisticParentCode.getName()
                            + statisticParentCode.getParent().getName());// 页面名称
                } else {
                    vo.setPage_code(statisticParentCode.getName());// 页面名称
                }
            }
            StatisticCode statisticCode = new StatisticCode();
            statisticCode.setCode(vo.getChannel_code());
            // 渠道名称
            statisticCode = statisticCodeService
                    .selectStatisticCode(statisticCode);
            vo.setChannel_code(statisticCode.getName());
            vo.setChannel_parent_code(statisticCode.getParent().getName());
        }

        Map<String, Object> resultMap = new HashMap<String, Object>();
        if (page != null) {
            resultMap.put("count", page.getTotal());
            resultMap.put("flowlist", list);
            resultMap.put("page", page);
        }
        return resultMap;
    }

    /**
     * 流量转化-不同详情
     *
     * @param channel_code
     * @param platform
     * @param platform_code
     * @param category_id
     * @param chooseTime
     * @param tab_id
     * @param land_code
     * @return
     * @throws ParseException
     */
    @RequestMapping("queryfunnel")
    @ResponseBody
    public Map<String, Object> queryFunnelNew(String channel_code,
                                              String platform, String platform_code, String category_id,
                                              @RequestParam("chooseTime") String chooseTime,
                                              @RequestParam("tab_id") String tab_id, String land_code)
            throws ParseException {
        List<String> StatisticCodeList = new ArrayList<String>();
        if (platform_code.equals("")) {
            StatisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName(platform);
        }
        Map<String, Object> param = new HashMap<String, Object>();
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        DateFormat format1 = new SimpleDateFormat("MM/dd/yyyy");
        String[] split = chooseTime.split("-");
        String start_date = split[0].trim();
        String end_date = split[1].trim();
        Date startDate = format1.parse(start_date);
        Date endDate = format1.parse(end_date);
        start_date = format.format(startDate);
        end_date = format.format(endDate);

        param.put("start_date", start_date);
        param.put("end_date", end_date);

        String sqlFlag = "1";
        String parent_id = null;
        String platform_all = null;
        if ("app".equalsIgnoreCase(tab_id)) {
            sqlFlag = "2";
            channel_code = "116yq5";
            if (platform == null || platform == "") {
                platform_all = "2g53";
            }

        } else if ("Wap".equalsIgnoreCase(tab_id)) {
            sqlFlag = "3";
            channel_code = "116yq5";
            if (platform == null || platform == "") {//platform为空，查询全部PC，wap的流量  modified by shibing 2017-08-25
                StatisticCodeList = statisticCodeService
                        .getDeviceCodeByLikeNamePcAndWap(platform);
            }
        } else if ("SEM".equalsIgnoreCase(tab_id)) {
            channel_code = "12h";
        } else if ("SEO".equalsIgnoreCase(tab_id)) {
            if (channel_code == null || channel_code == "") {
                parent_id = "7";
            }

        } else if ("Society".equalsIgnoreCase(tab_id)) {
            if (channel_code == null || channel_code == "") {
                parent_id = "6";
            }
        }
        param.put("platform_code", platform_code);
        param.put("parent_id", parent_id);
        param.put("channel_code", channel_code);
        param.put("platform_all", platform_all);
        param.put("land_code", land_code);
        param.put("StatisticCodeList", StatisticCodeList);
        List<FlowStatisticsVo> list = null;
        if ("2".equals(sqlFlag)) {
            list = flowStatisticsService.queryFlowbyApp(param);
        } else if ("3".equals(sqlFlag)) {//PC/M站直接访问流量统计 add by shibing 2017-08-25
            list = flowStatisticsService.queryFlowbyChannelWap(param);
        } else {
            list = flowStatisticsService.queryFlowbyChannel(param);
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("list", list);
        return resultMap;
    }

    @RequestMapping("queryFlowStatisticsData")
    @ResponseBody
    public Map<String, Object> queryFlowStatisticsData(
            @RequestParam("chooseTime") String chooseTime)
            throws ParseException {
        Map<String, Object> param = new HashMap<String, Object>();
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        DateFormat format1 = new SimpleDateFormat("MM/dd/yyyy");
        String[] split = chooseTime.split("-");
        String start_date = split[0].trim();
        String end_date = split[1].trim();
        Date startDate = format1.parse(start_date);
        Date endDate = format1.parse(end_date);
        start_date = format.format(startDate);
        end_date = format.format(endDate);
        param.put("start_date", start_date);
        param.put("end_date", end_date);

        List<String> StatisticCodeList = statisticCodeService
                .getDeviceCodeByLikeName("");

        param.put("StatisticCodeList", StatisticCodeList);

        FlowData flowData = flowStatisticsService
                .queryFlowStatisticsData(param);

        Long totalAmount = 0l;
        List<FlowAndRateData> list = null;
        if (flowData != null) {
            Long appFlowAmount = flowData.getAppFlowAmount() != null ? flowData
                    .getAppFlowAmount() : 0l;
            Long wapFlowAmount = flowData.getWapFlowAmount() != null ? flowData
                    .getWapFlowAmount() : 0l;
            Long semFlowAmount = flowData.getSemFlowAmount() != null ? flowData
                    .getSemFlowAmount() : 0l;
            Long seoFlowAmount = flowData.getSeoFlowAmount() != null ? flowData
                    .getSeoFlowAmount() : 0l;
            Long societyFlowAmount = flowData.getSocietyFlowAmount() != null ? flowData
                    .getSocietyFlowAmount() : 0l;
            flowData.setAppFlowAmount(appFlowAmount);
            flowData.setWapFlowAmount(wapFlowAmount);
            flowData.setSemFlowAmount(semFlowAmount);
            flowData.setSeoFlowAmount(seoFlowAmount);
            flowData.setSocietyFlowAmount(societyFlowAmount);
            totalAmount = appFlowAmount + wapFlowAmount + semFlowAmount
                    + seoFlowAmount + societyFlowAmount;
            // totalAmount = flowData.getAppFlowAmount()
            // +flowData.getWapFlowAmount() +flowData.getSemFlowAmount()
            // +flowData.getSeoFlowAmount() + flowData.getSocietyFlowAmount()
            // /*+ flowData.getSpecialFlowAmount()*/;

            list = flowDataToFlowAndRateList(flowData,
                    totalAmount);
        }


        int defaultLength = 5;
        Long[] seriesDataf = new Long[defaultLength];
        String[] xAxisDataf = new String[defaultLength];
        if (list != null && !list.isEmpty()) {
            int i = 0;
            for (FlowAndRateData flowStatistics : list) {
                if (i < defaultLength) {
                    seriesDataf[i] = flowStatistics.getFlowData();
                    xAxisDataf[i] = i + 1 + "";
                }
                i++;
            }
        }

        Map<String, Object> resultMap = new HashMap<String, Object>();

        resultMap.put("list", list);
        resultMap.put("amountF", totalAmount);
        resultMap.put("defaultLength", defaultLength);
        resultMap.put("seriesDataf", seriesDataf);
        resultMap.put("xAxisDataf", xAxisDataf);
        return resultMap;

    }

    /**
     * @param @param flowData 设定文件
     * @return void 返回类型
     * @throws
     * @Title: flowDataToFlowAndRateList
     * @Description: TODO(将查处的数据转换为list)
     */
    private List<FlowAndRateData> flowDataToFlowAndRateList(FlowData flowData,
                                                            Long totalAmount) {
        // TODO Auto-generated method stub
        List<FlowAndRateData> list = new ArrayList<FlowAndRateData>();
        DecimalFormat df = new DecimalFormat("#.00");

        FlowAndRateData data = new FlowAndRateData();
        data.setFlowSource("APP直接访问");
        if (flowData != null) {
            data.setFlowData(flowData.getAppFlowAmount());
        }
        list.add(data);

        FlowAndRateData data1 = new FlowAndRateData();
        data1.setFlowSource("M站直接访问");
        if (flowData != null) {
            data1.setFlowData(flowData.getWapFlowAmount());
        }
        list.add(data1);

        FlowAndRateData data2 = new FlowAndRateData();
        data2.setFlowSource("SEM");
        if (flowData != null) {
            data2.setFlowData(flowData.getSemFlowAmount());
        }
        list.add(data2);

        FlowAndRateData data3 = new FlowAndRateData();
        data3.setFlowSource("SEO");
        if (flowData != null) {
            data3.setFlowData(flowData.getSeoFlowAmount());
        }
        list.add(data3);

        FlowAndRateData data4 = new FlowAndRateData();
        data4.setFlowSource("社交分享");
        if (flowData != null) {
            data4.setFlowData(flowData.getSocietyFlowAmount());
        }
        list.add(data4);
        // 暂时不考虑专题和其它
        /*
         * FlowAndRateData data5 = new FlowAndRateData();
		 * data5.setFlowSource("其它"); if(flowData != null){
		 * data5.setFlowData(flowData.getTotalFlowAmount()-totalAmount); }
		 * list.add(data5);
		 * 
		 * FlowAndRateData data6 = new FlowAndRateData();
		 * data6.setFlowSource("专题"); if(flowData != null){
		 * data6.setFlowData(flowData.getSpecialFlowAmount()); }
		 * list.add(data6);
		 */
        // 计算各来源占比
        if (list != null && !list.isEmpty()) {
            for (FlowAndRateData flowStatistics : list) {
                if (totalAmount != 0 && flowStatistics.getFlowData() > 0) {
                    String rat = df.format(((double) flowStatistics
                            .getFlowData() / totalAmount) * 100);
                    flowStatistics.setFlowRate(rat);
                } else {
                    flowStatistics.setFlowRate("0.00");
                }
            }
        }

        // 各来源按照流量进行降序排列
        Collections.sort(list, new Comparator<FlowAndRateData>() {

            /*
             * int compare(FlowAndRateData o1, FlowAndRateData o2) 返回一个基本类型的整型，
             * 返回负数表示：o1 小于o2， 返回0 表示：o1和o2相等， 返回正数表示：o1大于o2。
             */
            public int compare(FlowAndRateData o1, FlowAndRateData o2) {

                // 按照流量进行降序排列
                if (o1.getFlowData() < o2.getFlowData()) {
                    return 1;
                }
                if (o1.getFlowData() == o2.getFlowData()) {
                    return 0;
                }
                return -1;
            }
        });

        return list;

    }

    @RequestMapping("channellist")
    @ResponseBody
    public Map<String, Object> channelList(
            @RequestParam("chooseTime") String chooseTime)
            throws ParseException {
        Map<String, String> param = new HashMap<String, String>();
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        DateFormat format1 = new SimpleDateFormat("MM/dd/yyyy");
        String[] split = chooseTime.split("-");
        String start_date = split[0].trim();
        String end_date = split[1].trim();
        Date startDate = format1.parse(start_date);
        Date endDate = format1.parse(end_date);
        start_date = format.format(startDate);
        end_date = format.format(endDate);
        param.put("start_date", start_date);
        param.put("end_date", end_date);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        return resultMap;
    }

    /**
     * 页面流量上下游溯源
     *
     * @param page_code
     * @param category_id
     * @param chooseTime
     * @param plat_form
     * @return
     * @throws ParseException
     */
    @RequestMapping("conversionlist")
    @ResponseBody
    public Map<String, Object> channelList(
            @RequestParam("page_code") String page_code,
            @RequestParam("category_id") String category_id,
            @RequestParam("chooseTime") String chooseTime,
            @RequestParam("plat_form") String plat_form,
            String pageCurrentNum,
            String productId,
            String pageSize) throws ParseException {
        List<String> statisticCodeList = null;
        if ("app".equals(plat_form)) {
            statisticCodeList = statisticCodeService.getDeviceCodeApp();
        } else if (!"".equals(plat_form)) {
            statisticCodeList = statisticCodeService.getDeviceCodeByLikeName(plat_form);
        }
        Map<String, Object> param = new HashMap<String, Object>();
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        DateFormat format1 = new SimpleDateFormat("MM/dd/yyyy");
        String[] split = chooseTime.split("-");
        String start_date = split[0].trim();
        String end_date = split[1].trim();
        Date startDate = format1.parse(start_date);
        Date endDate = format1.parse(end_date);
        start_date = format.format(startDate);
        end_date = format.format(endDate);
        if (page_code.startsWith("3PinD") || page_code.startsWith("3zhTi")) {
            page_code = category_id;
            category_id = "";
        }

        param.put("category_id", category_id);
        param.put("start_date", start_date);
        param.put("end_date", end_date);
        param.put("page_code", page_code);
        param.put("statisticCodeList", statisticCodeList);
        param.put("product_id", productId);
        Map<String, Long> result = flowStatisticsService.queryFlowFromAndToSum(param);
        param.put("pageCurrentNum", pageCurrentNum);
        param.put("pageSize", pageSize);

        List<FlowStatisticsVo> fromList = flowStatisticsService.queryFlowFromList(param).getList();

        List<FlowStatisticsVo> toList = flowStatisticsService.queryFlowToList(param).getList();

        for (FlowStatisticsVo flowStatisticsVo : fromList) {
            String code = flowStatisticsVo.getParent_page_code() != null ? flowStatisticsVo
                    .getParent_page_code() : "";
            if (code.equals("3XagQ") || code.equals("3TXDD")
                    || code.equals("3DaiZ") || code.equals("3ZhiW")) {
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                // 获得相匹配的品类的信息
                String categoryId = CommonParentType
                        .getCategoryShowName(flowStatisticsVo
                                .getParent_category_id());
                if (StringUtils.isEmpty(categoryId)) {
                    categoryId = "其他";
                }
                flowStatisticsVo.setParent_category_id(categoryId);// 页面名称
                flowStatisticsVo.setParent_page_code(pageBusinessTypes);// 页面业务类型
            } else if (code.startsWith("3PinD") || code.startsWith("3zhTi")
                    || code.startsWith("3SouS")) {
                String category_id1 = "";
                if (code.startsWith("3PinD")) {
                    category_id1 = "3PinD";
                } else if (code.startsWith("3zhTi")) {
                    category_id1 = "3zhTi";
                } else if (code.startsWith("3SouS")) {
                    category_id1 = "3SouS";
                }
                StatisticCode statisticParentCode = new StatisticCode();
                statisticParentCode.setCode(category_id1);
                // 根据条件查询code对象
                statisticParentCode = statisticCodeService
                        .selectStatisticCode(statisticParentCode);
                String categoryId = "";// 页面业务类型
                if (statisticParentCode != null) {
                    categoryId = statisticParentCode.getName();
                }
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                flowStatisticsVo.setParent_page_code(categoryId);// 页面业务类型
                flowStatisticsVo.setParent_category_id(pageBusinessTypes);// 页面名称
            } else {
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                flowStatisticsVo.setParent_page_code(pageBusinessTypes);// 页面业务类型
                flowStatisticsVo.setParent_category_id("");
            }
        }

        for (FlowStatisticsVo flowStatisticsVo : toList) {
            String code = flowStatisticsVo.getPage_code();
            if (code.equals("3XagQ") || code.equals("3TXDD")
                    || code.equals("3DaiZ") || code.equals("3ZhiW")) {
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                // 获得相匹配的品类的信息
                String categoryId = CommonParentType
                        .getCategoryShowName(flowStatisticsVo.getCategory_id());
                if (StringUtils.isEmpty(categoryId)) {
                    categoryId = "其它";
                }
                flowStatisticsVo.setCategory_id(categoryId);// 页面名称
                flowStatisticsVo.setPage_code(pageBusinessTypes);// 页面业务类型
            } else if (code.startsWith("3PinD") || code.startsWith("3zhTi")
                    || code.startsWith("3SouS")) {
                String category_id1 = "";
                if (code.startsWith("3PinD")) {
                    category_id1 = "3PinD";
                } else if (code.startsWith("3zhTi")) {
                    category_id1 = "3zhTi";
                } else if (code.startsWith("3SouS")) {
                    category_id1 = "3SouS";
                }
                StatisticCode statisticParentCode = new StatisticCode();
                statisticParentCode.setCode(category_id1);
                // 根据条件查询code对象
                statisticParentCode = statisticCodeService
                        .selectStatisticCode(statisticParentCode);
                String categoryId = "";// 页面业务类型
                if (statisticParentCode != null) {
                    categoryId = statisticParentCode.getName();
                }
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                flowStatisticsVo.setPage_code(categoryId);// 页面业务类型
                flowStatisticsVo.setCategory_id(pageBusinessTypes);// 页面名称
            } else {
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                flowStatisticsVo.setCategory_id("");// 页面名称
                flowStatisticsVo.setPage_code(pageBusinessTypes);// 页面业务类型
            }
        }

        Long amountF = result.get("amountF");
        Long amountT = result.get("amountT");
        Long amountFO = 0L;
        Long amountTO = 0L;

        DecimalFormat df = new DecimalFormat("#0.00");

        if (fromList != null && !fromList.isEmpty()) {
            for (FlowStatisticsVo flowStatistics : fromList) {
                if (amountF != 0 && flowStatistics.getAmount() > 0) {
                    String rat = df
                            .format(((double) flowStatistics.getAmount() / amountF) * 100);
                    flowStatistics.setRate(rat);
                }
            }
            if("1".equals(pageCurrentNum) && "".equals(productId)){
                for (FlowStatisticsVo flowStatistics : fromList) {
                    amountFO += flowStatistics.getAmount();
                }
                FlowStatisticsVo fs = new FlowStatisticsVo();
                fs.setParent_page_code("其它");
                fs.setParent_category_id("");
                fs.setAmount(amountF-amountFO);
                fs.setRate( df.format(((double) fs.getAmount()/ amountF) * 100));
                fromList.add(fs);
            }

        }
        if (toList != null && !toList.isEmpty()) {
            for (FlowStatisticsVo flowStatistics : toList) {
                if (amountT != 0 && flowStatistics.getAmount() > 0) {
                    String rat = df
                            .format(((double) flowStatistics.getAmount() / amountT) * 100);
                    flowStatistics.setRate(rat);
                }
            }
            if("1".equals(pageCurrentNum) && "".equals(productId)) {
                for (FlowStatisticsVo flowStatistics : toList) {
                    amountTO += flowStatistics.getAmount();
                }
                FlowStatisticsVo fs = new FlowStatisticsVo();
                fs.setPage_code("其它");
                fs.setCategory_id("");
                fs.setAmount(amountT-amountTO);
                fs.setRate(df.format(((double) fs.getAmount()/ amountT) * 100));
                toList.add(fs);
            }
        }

        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("fromList", new PageInfo<>(fromList));
        resultMap.put("toList", new PageInfo<>(toList));
        resultMap.put("amountF", amountF);
        resultMap.put("amountT", amountT);
        return resultMap;
    }

    /**
     * 查询坑位详情
     * @param page_code
     * @param chooseTime
     * @param plat_form
     * @return
     * @throws ParseException
     */
    @RequestMapping("channelDetailList")
    @ResponseBody
    public Map<String, Object> channelDetailList(
            @RequestParam("page_code") String page_code,
            @RequestParam("category_id") String category_id,
            @RequestParam("chooseTime") String chooseTime,
            @RequestParam("plat_form") String plat_form,String type) throws ParseException {
        List<String> statisticCodeList = null;
        if ("app".equals(plat_form)) {
            statisticCodeList = statisticCodeService.getDeviceCodeApp();
        } else if (!"".equals(plat_form)) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName(plat_form);
        }
        Map<String, Object> param = new HashMap<String, Object>();
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        DateFormat format1 = new SimpleDateFormat("MM/dd/yyyy");
        String[] split = chooseTime.split("-");
        String start_date = split[0].trim();
        String end_date = split[1].trim();
        Date startDate = format1.parse(start_date);
        Date endDate = format1.parse(end_date);
        start_date = format.format(startDate);
        end_date = format.format(endDate);
        if (page_code.startsWith("3PinD") || page_code.startsWith("3zhTi")) {
            page_code = category_id;
            category_id = "";
        }
        param.put("category_id", category_id);
        param.put("start_date", start_date);
        param.put("end_date", end_date);
        param.put("page_code", page_code);
        param.put("page", "3PinDuau");//目前只有周边游"3PinDuau"
        param.put("statisticCodeList", statisticCodeList);
        List<FlowStatisticsVo> List = null;
        if("1".equals(type)){
            List = flowStatisticsService
                    .queryFlowDetailFromList(param);
        }else{
            List = flowStatisticsService
                    .queryFlowDetailToList(param);
        }

        Long amountT = 0L;
        DecimalFormat df = new DecimalFormat("#0.00");

        if (List != null && !List.isEmpty()) {
            for (FlowStatisticsVo flowStatistics : List) {
                amountT += flowStatistics.getAmount();
            }
            for (FlowStatisticsVo flowStatistics : List) {
                if (amountT != 0 && flowStatistics.getAmount() > 0) {
                    String rat = df
                            .format(((double) flowStatistics.getAmount() / amountT) * 100);
                    flowStatistics.setRate(rat);
                }
            }
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("list",List);
        return resultMap;
    }

    private void initCCMap() {
        if (ccMap.isEmpty()) {
            List<ContinuityCode> list = flowStatisticsService
                    .queryContinuityCode();
            if (list != null && !list.isEmpty()) {
                for (ContinuityCode continuityCode : list) {
                    if (ccMap.get(continuityCode.getCode()) == null) {
                        if (continuityCode.getCode() != null
                                && continuityCode.getCode() != "") {
                            synchronized (ccMap) {
                                ccMap.put(continuityCode.getCode(),
                                        continuityCode);
                            }
                        }

                    }

                }
            }
        }
    }

    public List<ContinuityCode> getCodeVoLikeName(String name) {
        initCCMap();
        List<ContinuityCode> list = new ArrayList<ContinuityCode>();
        Set<Entry<String, ContinuityCode>> set = ccMap.entrySet();
        for (Entry<String, ContinuityCode> entry : set) {
            if (entry.getValue() != null && entry.getValue().getName() != null
                    && entry.getValue().getName().contains(name)) {
                list.add(entry.getValue());
            }
        }
        return list;
    }

    public List<String> getCodeLikeName(String name) {
        initCCMap();
        List<String> list = new ArrayList<String>();
        Set<Entry<String, ContinuityCode>> set = ccMap.entrySet();
        for (Entry<String, ContinuityCode> entry : set) {
            if (entry.getValue() != null && entry.getValue().getName() != null
                    && entry.getValue().getName().contains(name)) {
                list.add(entry.getValue().getCode());
            }
        }
        return list;
    }

    public List<String> getCodeByParent(String parent_id) {
        initCCMap();
        List<String> list = new ArrayList<String>();
        Set<Entry<String, ContinuityCode>> set = ccMap.entrySet();
        for (Entry<String, ContinuityCode> entry : set) {
            if (entry.getValue() != null && entry.getValue().getName() != null
                    && entry.getValue().getParent_id().equals(parent_id)) {
                list.add(entry.getValue().getCode());
            }
        }
        return list;
    }

    public Map<String, Object> getResult() {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", "-1");
        return result;
    }

    /**
     * 获得频道code
     */
    @RequestMapping("getPindaoCode")
    @ResponseBody
    public Map<String, Object> getPindaoCode(String name) {
        Map<String, Object> result = getResult();
        StatisticCode code = new StatisticCode();
        code.setParentId(280);
        code.setName(name);
        StatisticCode statisticCode = statisticCodeService
                .selectStatisticCode(code);
        result.put("statisticCode", statisticCode);
        return result;
    }

    /**
     * 获得频道子集
     */
    @RequestMapping("getPindaoParent")
    @ResponseBody
    public Map<String, Object> getPindaoParent() {
        Map<String, Object> result = getResult();
        List<StatisticCode> statisticCodeList = statisticCodeService
                .getLikeCodeObjNotParent("3PinD");
        result.put("statisticCodeList", statisticCodeList);
        return result;
    }

    /**
     * 获得所有品类
     */
    @RequestMapping("getAllCategory")
    @ResponseBody
    public Map<String, Object> getAllCategoryList() {
        Map<String, Object> result = getResult();
        CommonParentType[] categorys = CommonParentType.geAllCategory();
        Map<String, String> categoryMap = new HashMap<String, String>();
        for (CommonParentType category : categorys) {
            categoryMap.put(category.getValue(), category.getShowName());
        }
        result.put("categoryMap", categoryMap);
        return result;
    }

    /**
     * 保存自定义漏斗
     */
    @RequestMapping("savaFunnel")
    @ResponseBody
    public void savaFunnel(@RequestParam("jsondata") String jsondata) {
        JSONObject jsonObject = JSONObject.fromObject(jsondata);
        FlowStatisticsFunnel funnel = new FlowStatisticsFunnel();
        funnel.setName(jsonObject.getString("name"));
        if (jsonObject.getString("funnelType").equals("品类")) {
            funnel.setFunnelType("0");
        } else {
            funnel.setFunnelType("1");
        }
        SysUser user = SystemSession.getUser();
        funnel.setOperator(user.getCharacterName());
        funnel.setCreateTime(new Date());
        funnel.setEditTime(new Date());
        int funnelId = 0;
        if (StringUtils.isNotEmpty(jsonObject.getString("funnelId"))) {
            funnelId = Integer.valueOf(jsonObject.getString("funnelId"));
            funnel.setFunnelId(funnelId);
            funnelService.updateFunnel(funnel);
            List<String> list = new ArrayList<>();
            list.add(String.valueOf(funnelId));
            funnel.setFunnelIds(list);
            funnelService.deleteFunnelDetail(funnel);
        } else {
            funnelService.insertFunnel(funnel);
            FlowStatisticsFunnel flowStatisticsFunnel = funnelService
                    .selectFunnel(funnel);
            funnelId = flowStatisticsFunnel.getFunnelId();
        }
        JSONArray jarry = jsonObject.getJSONArray("list");
        for (int i = 0; i < jarry.size(); i++) {
            JSONObject obj = jarry.getJSONObject(i);
            String stepIndex = obj.getString("stepIndex");
            String pageName = obj.getString("pageName");
            String paramId = obj.getString("categoryName");
            String pageCode = obj.getString("pageCode");
            FlowStatisticsFunnel f = new FlowStatisticsFunnel();
            f.setFunnelId(funnelId);
            f.setStepIndex(Integer.valueOf(stepIndex));
            f.setPageName(pageName);
            if (jsonObject.getString("funnelType").equals("品类")) {
                f.setParamId(Integer.valueOf(CommonParentType
                        .getCategoryValueByShowName(paramId)));
            } else {
                f.setParamId(Integer.valueOf(paramId));
            }
            f.setPageCode(pageCode);
            funnelService.insertFunnelDetail(f);
        }
    }

    /**
     * 保存自定义漏斗
     */
    @RequestMapping("deleteFunnel")
    @ResponseBody
    public void deleteFunnel(@RequestParam("funnelIds") String funnelIds) {
        String[] funnelIdArr = funnelIds.split(",");
        FlowStatisticsFunnel funnel = new FlowStatisticsFunnel();
        funnel.setFunnelIds(Arrays.asList(funnelIdArr));
        funnelService.deleteFunnel(funnel);
        funnelService.deleteFunnelDetail(funnel);
    }

    /**
     * 筛选出漏斗详情
     */
    @RequestMapping("getFunnelDetailList")
    @ResponseBody
    public Map<String, Object> getFunnelDetailList(FlowStatisticsFunnel funnel) {
        Map<String, Object> result = getResult();
        funnelService.updateFunnel(funnel);
        List<FlowStatisticsFunnel> funnelDetailList = funnelService
                .selectFunnelDetail(funnel);
        if (funnelDetailList != null && funnelDetailList.size() > 0) {
            for (FlowStatisticsFunnel f : funnelDetailList) {
                if (f.getFunnelType().equals("0")) {
                    f.setFunnelType("品类");
                    f.setCategoryName(CommonParentType
                            .getCategoryShowName(String.valueOf(f.getParamId())));
                } else {
                    f.setFunnelType("产品");
                }
            }
        }
        result.put("funnelDetailList", funnelDetailList);
        return result;
    }

    /**
     * 筛选出指定漏斗
     */
    @RequestMapping("selectFunnel")
    @ResponseBody
    public Map<String, Object> selectFunnel(FlowStatisticsFunnel funnel) {
        Map<String, Object> result = getResult();
        if (StringUtils.isNotEmpty(funnel.getFunnelType())) {
            if (funnel.getFunnelType().equals("品类")) {
                funnel.setFunnelType("0");
            } else {
                funnel.setFunnelType("1");
            }

        }
        FlowStatisticsFunnel data = funnelService.selectFunnel(funnel);
        result.put("funnel", data);
        return result;
    }

    /**
     * 筛选出所有漏斗
     */
    @RequestMapping("getAllFunnelList")
    @ResponseBody
    public Map<String, Object> getAllFunnelList(FlowStatisticsFunnel funnel) {
        Map<String, Object> result = getResult();
        PageInfo<FlowStatisticsFunnel> page = funnelService
                .selectAllFunnel(funnel);
        result.put("pageData", page);
        SysUser user = SystemSession.getUser();
        List<Menu> menuList = menuService.getMenuList(user);
        if (null != menuList && menuList.size() > 0) {
            for (Menu menu : menuList) {
                if (StringUtils.isNotEmpty(menu.getPermission())) {
                    if (menu.getPermission().contains("sys:funnel:new")) {
                        result.put("newFunnelPermission", true);
                    }
                    if (menu.getPermission().contains("sys:funnel:delete")) {
                        result.put("deleteFunnelPermission", true);
                    }
                    if (menu.getPermission().contains("sys:funnel:edit")) {
                        result.put("editFunnelPermission", true);
                    }

                }
            }
        }
        return result;
    }

    /**
     * 筛选出所有漏斗
     */
    @RequestMapping("getFunnelChart")
    @ResponseBody
    public Map<String, Object> getFunnelChart(
            @RequestParam("chooseTime") String chooseTime,
            @RequestParam("platForm") String platForm,
            @RequestParam("version") String version,
            @RequestParam("visitType") String visitType,
            @RequestParam("funnelId") String funnelId) throws Exception {
        Map<String, Object> result = getResult();
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd");
        String start_date = chooseTime.split("-")[0];
        String end_date = chooseTime.split("-")[1];
        start_date = sdf1.format(sdf.parse(start_date)).replace("/", "");
        end_date = sdf1.format(sdf.parse(end_date)).replace("/", "");
        List<String> statisticCodeList = new ArrayList<String>();
        if (StringUtils.isEmpty(platForm)) {
            statisticCodeList.add(version);
        } else if (platForm.equals("app")) {
            statisticCodeList = statisticCodeService.getDeviceCodeApp();
        } else if (platForm.equals("ios")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("ios");
        } else if (platForm.equals("android")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("android");
        } else if (platForm.equals("wap")) {
            statisticCodeList = statisticCodeService
                    .getDeviceCodeByLikeName("wap");
        } else if (platForm.equals("all")) {
            statisticCodeList = statisticCodeService.getLikeCodes("2");
        }
        FlowFunnelData funnelData = new FlowFunnelData();
        funnelData.setBeginDate(start_date);
        funnelData.setEndDate(end_date);
        funnelData.setPlatformCodeList(statisticCodeList);
        FlowStatisticsFunnel funnel = new FlowStatisticsFunnel();
        funnel.setFunnelId(Integer.valueOf(funnelId));
        List<FlowStatisticsFunnel> funnelDetailList = funnelService
                .selectFunnelDetail(funnel);
        String reg = "";
        if (funnelDetailList != null && funnelDetailList.size() > 0) {
            int i = 0;
            for (FlowStatisticsFunnel f : funnelDetailList) {
                if (f.getFunnelType().equals("0")) {
                    f.setCategoryName(CommonParentType
                            .getCategoryShowName(String.valueOf(f.getParamId())));
                }
                if (i > 0) {
                    reg += ".*";
                }
                reg += f.getPageCode();
                if (f.getFunnelType().equals("0")) {
                    if (f.getPageCode().startsWith("3PinD")) {
                        reg += ",-?[0-9]*,-?[0-9]*";
                    } else {
                        reg += "," + f.getParamId() + ",-?[0-9]*";
                    }

                } else {
                    if (f.getPageCode().startsWith("3PinD")) {
                        reg += ",-?[0-9]*,-?[0-9]*";
                    } else {
                        reg += ",-?[0-9]*," + f.getParamId();
                    }
                }
                long value = getPathNum(visitType, reg, funnelData);
                logger.info("---------第" + i + "步骤值:" + value);
                f.setAmount(value);
                i++;
            }
            result.put("funnelName", funnelDetailList.get(0).getName());
        }
        result.put("funnelDetailList", funnelDetailList);
        return result;
    }

    /**
     * @param @param  type uv/session
     * @param @param  reg "(.*3PinDsyw,-1,-1.*3PinDsyw,-1,-1.*)"路径正则
     * @param @param  param 相关的平台，时间的查询条件
     * @param @return 设定文件
     * @return int 返回类型
     * @throws
     * @Title: getPathNum
     * @Description: 自定义漏斗获取uv/session 数据量
     */
    private Long getPathNum(String type, String reg, FlowFunnelData param) {
        String operPath = "";
		/* uv/session 查询不通的表 */
        if (type.equals("uv")) {
            operPath = "dtOperPath";
        } else {
            operPath = "sessionOperPath";
        }
        reg = "(.*" + reg + ".*)";
        logger.info("-------------reg-----------" + reg);
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(
                        QueryBuilders
                                .boolQuery()
                                .must(QueryBuilders.termsQuery("platformCode",
                                        param.getPlatformCodeList()))
                                .must(QueryBuilders.rangeQuery("operateDate")
                                        .from(param.getBeginDate())
                                        .to(param.getEndDate())
                                        .includeLower(true).includeUpper(true))
                                .must(QueryBuilders.regexpQuery("operatePath",
                                        reg))).withIndices("flow_v1")
                .withPageable(new PageRequest(0, 10000000)).withTypes(operPath)
                .build();
        long amount = template.count(searchQuery,
                FlowFunnelData.class);
        return amount;
    }

}
